package org.chipu.jnids.sce.profile;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;

public final class CombinedStats {
	@Nonnegative
	private int numberOfCombinedStats;
	@Nonnull
	private Stats stats;

	public CombinedStats(@Nonnull Stats s) {
		if (s == null)
			throw new IllegalArgumentException();
		stats = s;
		numberOfCombinedStats = 1;
	}

	public void add(Stats s) {
		stats = new Stats(stats.dataCount + s.dataCount, ponderate(stats.average, s.average), ponderate(
			stats.standardDeviation, s.standardDeviation), ponderate(stats.skewness, s.skewness), ponderate(
			stats.kurtosis, s.kurtosis));
		numberOfCombinedStats++;
	}

	private float ponderate(float a, float b) {
		return (a * numberOfCombinedStats + b) / (numberOfCombinedStats + 1);
	}

	@Override
	public String toString() {
		return "CombinedStats (" + numberOfCombinedStats + "): " + stats;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null || !obj.getClass().isAssignableFrom(getClass()))
			return false;
		CombinedStats o = (CombinedStats) obj;
		return numberOfCombinedStats == o.numberOfCombinedStats && stats.equals(o.stats);
	}

	public Stats getStats() {
		return stats;
	}

	public String encode() {
		return "<combinedstat count=\"" + numberOfCombinedStats + "\">" + stats.encode() + "</combinedstat>";
	}

	public static CombinedStats decode(String s) {
		assert s.startsWith("<combinedstat ");
		int i = s.indexOf("<stat ");
		CombinedStats rta = new CombinedStats(Stats.decode(s.substring(i, s.indexOf("/>") + 2)));
		rta.numberOfCombinedStats = StatType.getIntValue(s, "count");
		return rta;
	}
}